package com.slt.developkitweb.util;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * @author yuelujie
 * @description
 * @date 2020/9/9
 */
public class AESUtils {

    private static final String AES_ALGORITHM = "AES/ECB/PKCS5Padding";

    public static String AES_Encrypt(Object plaintext, String Key,String EncryptMode) {
        String PlainText=null;
        try {
            PlainText=plaintext.toString();
            if (Key == null) {
                return null;
            }
//            Key = getMD5(Key);
            byte[] raw = Key.getBytes("utf-8");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/"+EncryptMode+"/PKCS5Padding");
            if(EncryptMode=="ECB") {
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
            }else {
                IvParameterSpec iv = new IvParameterSpec(Key.getBytes("utf-8"));//使用CBC模式，需要一个向量iv，可增加加密算法的强度
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            }
            byte[] encrypted = cipher.doFinal(PlainText.getBytes("utf-8"));
            String encryptedStr=new String(new BASE64Encoder().encode(encrypted));
            return encryptedStr;
            //return new String(encrypted);//此处使用BASE64做转码功能，同时能起到2次加密的作用。
        } catch (Exception ex) {
            System.out.println(ex.toString());
            return null;
        }
    }

    /**
     * AES解密
     *
     * @param cipertext 密文
     * @param Key 密钥
     * @param EncryptMode AES加密模式，CBC或ECB
     * @return 该密文的明文
     */
    public static String AES_Decrypt(Object cipertext, String Key,String EncryptMode) {
        String CipherText=null;
        try {
            CipherText=cipertext.toString();
            // 判断Key是否正确
            if (Key == null) {
                //System.out.print("Key为空null");
                return null;
            }
//            Key=getMD5(Key);
            byte[] raw = Key.getBytes("utf-8");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher=Cipher.getInstance("AES/"+EncryptMode+"/PKCS5Padding");
            if(EncryptMode=="ECB") {
                cipher.init(Cipher.DECRYPT_MODE, skeySpec);
            }
            else
            {
                IvParameterSpec iv = new IvParameterSpec(Key.getBytes("utf-8"));//使用CBC模式，需要一个向量iv，可增加加密算法的强度
                cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            }
            byte[] encrypted1 = new BASE64Decoder().decodeBuffer(CipherText);//先用base64解密
            //byte[] encrypted1 = CipherText.getBytes();
            try {
                byte[] original = cipher.doFinal(encrypted1);
                String originalString = new String(original,"utf-8");
                return originalString;
            } catch (Exception e) {
                System.out.println(e.toString());
                return null;
            }
        } catch (Exception ex) {
            System.out.println(ex.toString());
            return null;
        }
    }
    /**
     * 进行MD5加密
     *
     * @param s 要进行MD5转换的字符串
     * @return 该字符串的MD5值的8-24位
     */
    public static String getMD5(String s){
        char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

        try {
            byte[] btInput = s.getBytes();
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            mdInst.update(btInput);
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str).substring(8,24);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 生成随机密钥
     * @param keySize 密钥大小推荐128 256
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static String generateSecret(int keySize) throws NoSuchAlgorithmException {
        KeyGenerator generator = KeyGenerator.getInstance("AES");
        generator.init(keySize, new SecureRandom());
        SecretKey key = generator.generateKey();
        return byteToHexString(key.getEncoded());
    }

    /**
     * byte数组转化为16进制字符串
     * @param bytes
     * @return
     */
    private static String byteToHexString(byte[] bytes){
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            String strHex=Integer.toHexString(bytes[i]);
            if(strHex.length() > 3){
                sb.append(strHex.substring(6));
            } else {
                if(strHex.length() < 2){
                    sb.append("0" + strHex);
                } else {
                    sb.append(strHex);
                }
            }
        }
        return  sb.toString();
    }
    // 获取 cipher
    private static Cipher getCipher(byte[] key, int model) throws Exception {
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
        cipher.init(model, secretKeySpec);
        return cipher;
    }
    // AES加密
    public static String encrypt(byte[] data, byte[] key) throws Exception {
        Cipher cipher = getCipher(key, Cipher.ENCRYPT_MODE);
        return Base64.getEncoder().encodeToString(cipher.doFinal(data));
    }

    // AES解密
    public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        Cipher cipher = getCipher(key, Cipher.DECRYPT_MODE);
        return cipher.doFinal(Base64.getDecoder().decode(data));
    }
    public static void main(String[] args) throws NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchPaddingException, UnsupportedEncodingException {

//        String key = Md5.getMd5Str(generateSecret(256)).substring(0,16);
        String key = "F49E8CAC66C376FC";
        System.out.println(key);
//        String enData = AES_Encrypt("你好测试hello", key,"CBC");
        String enData = "4MM/GFNwxy7GcnVleQSb54GC/8hsxgr0QG/DxcViFqXd3pFshsOeB3eiGILBYI1hWFJxeV2pfjeMk3IUgod2GYboU28ajMHPlAvhrEnhPAflXaaSCshLvwBsj9sYn482wX6N8Ks9rgEiRD33HCJIu84csjIoIWje+/dTBwTsu3WwyU5hRMTO4zBV/6HFDNrCmFy7KD0cg89N3g/mjqga3dNEiDhtCqkWqBmEEikit2RWNPlqvBMwsiuXUlCRqFM8bhRbX76MHSBR3FTqeAz41SdCo+P0dUiscmvQqeWhqZd1ybEhqhzNi6D/qrfAuWiAO87WIx7nMLvdNGzfMGaIOvv1zCkCk95OpXhr9/JPiiTFEvc5UHwrmQVZllaavBj+EQnGY3rAvin3OSlay5Vct/cDO/P44eO8dc4KRGh60XP9NEzGsuZ6nW0A1BoSbxk+PTdKWpUnJoAPHu0srZumcyKxGm6xY87aZVpq297BdB0GsNDgGUwpweCb+9z6oC19Mka0mW2qayu5lKfHbcebbAOB7ZHhmduEVhcCPSoWB2SYg9weou7oJ/BfhS5pU0CsUU66tJW1XK1RXdwcr1/32omh2TTHObqpIPTHOVvFufRSAF0/59LXyxIyKX665j+oJVclebNzyeQ2DrBja0Mfr8kLMrzWeollSTkL5DLF2KqJN8t5jsre07Aq+0bzvjIkfRE/hgGMHM1dcXoVI1Oyki4bl4Y+lpQnnURXLx/aimDACAxetl2isHZ9V63wCyP66R8/NrJq62+VHyCmX/NdGtABoN0H2uCG1/31+wzUSBcSG2zKbyXi0oQvRr2elQoChVN7EgZ65PP1dfeUw0kPNHoz7UWLNqXM4s7YwRe/YRcrWdm5fPEQskvQA01vRvkHPMUQmVywBcGSaOE+4tsUkaEjfpFgxgxG7+UAMOEpv0QEYAZ94S3RphtSH9MJzbbyxQCe9mMvG8hg0WyxkgyT3lAVf8WkOOr4d858HT5RFbLrNYGKd/BdtFZikwZzt5lqd/cNO56+0123wOhTxWCQuVuQLjnQosBofxxD2ZBZ8cG4BD2K4mqBBEoaX5FZ4hx6jKmt6+qp3jpSTBPiK+AbHI2/Bp7jHUYshN9jxgFwdIH40HSXLcMJtUAlZAFyMjcDpPOo4Hpp5Iu3M89skdkcSsBG14YR5jPYwaIrEP13d4FgZC1c+/WE8a4E+8puckxrcwrnHAFBffPAZDAvqTNJIcB5stEylIsvHBOkYJE4XmncPnJ0akgpHMuZxwV+FHrouZLgF+MVqIEM0FABoBzjZLCDAyKu9yt0uNOFwTAiLo8q0t5YA/83U3u9vtQ8Xp3kojHQYm8v0oCfEgbNA0AjCY+N7tkOHR5UwfHZNr8foRarGKZo3PitEX07ge3hKQulDxJy4jbB5HuuF4lZq5wCV79WsGG1+qXK8P3kF7SHTw191oc9BPvGkmSlE2oBemSR+toLJnt3OYvdVyNMwq/b+zuB0qKi7l66TEArQ+DkO2OJcouiMTKmrFokp/SQe03s2qpzwLVRRwF1QTvsbmcgMEmlZhru3eaqiJS5tsDJRJCAajvzXFd78SSh+XZIpqwuqZq7LLPJ1X0ySgpJKSBQVptAIPLF0eIsi+8jcnOcAHTMq7mflsClqAhinj2J50eaoave+VS0H0At9ch3oAhVC5y6if87TuBEdrNV397N7GEpgmEXMN5p10ywfGAjx5skS7AutTFoGOu79zChv5JXDaixp1yg/pwEMhctesIzfO639PvAha60v7wnTRNizZ+BDpoKPs3gSCu6GM19UpgEMoeLx48hTtkkIrX8w5shuF8Ok4qP0P93cpPEeWHd/EE2/XL4y8AUP7E4Bu17EuXN3eaRhVgwS2nN3hCpB/l+D+9vRla4sHItJd3BNqIgBnH20YSGHXjlEhOx4//ZeshDmhQf4qovaIKTZtMnkMwhfGznqg8rjXGijVuMqTQqZFLwa/Eua4eSGUR4E4KxjeI2SxJRR5rVQ4lOnLURi0mVDKiKw3Xoy1SLAKviykT6HsqfV/4zP7UrAEsvoXeyfyysU0m2wISZMzRAa8wKvFD7evvY3T0ycnXZjau9vSa+q9N543whi7OQdEc+YvtFXxdKdFyLSjHq2rb1MwFVOIn0CvmKKiN5MgvW7u3CtrJ9Je/GQle0Wk3cBKwMi5nJdouzwJC9QpXbnKfINGgQC/RlKlm2RMMQh8MXSBrOUF4FFeBmssO0QJO0CwjfwM2crKZ8pI8uUJsVMoy+pJcOav+H/I7PDlSsn/fiqZLk0dYSKvLh5YbYSBsUl0U0cryxWlts8exAEc2Koa/TaSqSSdCJzfnCXPGHtv2Yle7FdG41imahgkfxm3uysNXl36Iy5GDI+myI1V2J9dUC8gUMZYJ59oaXzu0OuX+2pYEOF8uwoFJph4CLAG9aaNbgoZslI0kcmr/nSzOrwM4s1mjr9YOiPXLP2dhcGe+p3ujBL2JjN9mklkzzuT2EQo3q7TEee7TLWQN0J6hDuGoYNekVxjUAxQH0ML4eOJH0Vw9gNPokbHNH6n7x21Z8LlCla1AR6WPJzvZjSd6KmgJHjfRg0Sgj9+AskPWZIdxhKB0MHoM0edJtW9zjJbyMEllH0+vs483kk2Os/Uei8CqthgMerzMiIwXVDvHwF3lZxgad1//zPyLkQfXvP7bvhCKYHhFeQOOCderntHBc9tpzjLTbAc+Buzihzi80iD9c/0jdLPZh3LjtWZeCI7tUfczUSq9pvme47BokrZWuLQumfLCZtnfy+T5gCHM8bqaAo+mJmfpSw9j3p9WjjfnWXyUZ1+WqZnMwEvPbHWGcxhS/Dw4WBG7V8m9YU10fKzfLr0NTcz3Sex4Twt6xr+5rDI+h8WKHjg99BRIEcpTw8nGar78ayyF0T4dKeh503mR3ICvI9iGZJbc1/SQyjvm337pPDtB//a6z1x/pkDPHhaw5FvLQq3tGUgsNCTyxZ/8qpeyPsAALBip/pTtb5Cb4ES+W42vbaqTafpIlLYNF4B+O08nIe7h1wp+j6Rl4RXEIHROZZEmgyphqaDP7MJnHAiE56qq321vZQ2W3vY5zcU6aRWVG+iIDczlbsZrwSZVXH6v9Tif57BZjZU80mqgeBkXyNyRlFJBr4eVoxP1CWFqf8iMHWmuhccAdMTRDwlM8MQvsCSVxKY827ucY0ydASW7bgXyUJhFsE9mBE0W4WCRn/wU/UajVC/eN8uAijqMqJ6dRdnU8/QdWfzDHPfu66a7HpPk5LJwt1T5J7gsmTIwSMyxlCgpPDjsNkT6ofbCGvSPE5TtTnZPKWLCq4csPm+P3S45kwc9IZ/N0RV3FNSJUtuiQuaKzV40Kx8260E4M4x8mpy40TeIm9BlmBOhnluhCevgLYR9SIh/N2FpRqqU0sSBweqodDpsQY9WBnhl9RAT+o5QLYI99wVKQaRkayz9VD3rU/Sp4YrHMPgrXEzmg0l1mdJ4PmRKqPa8t8UMEbRoSQotbNlqZ6AUBwjjQ8tv+l36PYo0OUjmw0W63ucxTVIdZ02exsmEL6ZLUr/lItfM3SEbiibYe9Z9M/g//8wwUs07FgmkfWmrAKps9qI2eLUdwG0On9ngVa7mO23FQSAUjd6mVfxSqks6Yi0I49dPnCcpRUZAQWxL5uhsfCtuvJ4LqEoNzF79gDfB+FgzDorfH8g6Iy9EQa6XRh0OWRMkm7CGja3xQou2ebcdQxNm7W8y0y0xSdN0IUzzOFLoZ/1wTPpXTltyUaDom+S0zZoqo+kZWqVYyIk88XQ06VW/Voh7xQf8359xx2fu39JeyqotQq971VZc+o/2JbaDPPJwbGcG0j9P10adXJo29nbY/c0weZBB472WBBv1LqINg1TwZHZBuxadl6PcGDhkRFEVOcaZhw6Ojp3cs+q9j7gpaSi+dFu467FzDTJp0UgQWyzxDqe2Fc8lRM8D0O/qw1MsUeet7TxLZar3j1uYLBPH3uOzNzM2zF9NH+vSIWFjw0/dNasp2IbOGzQiQSvQN8bcHq0/Yn3yFb+kak7b1CiCBa8ByvSmo4zepNTVqOOzODwV9zBbVz749qPIhVhMLmDKTlTU1rbwq6oYoa3rRoOxuXABCpYVbU8opie/NpniIjjZzlk/R5pSo6WSk26JhZckVmFUhR8g6cLSMQAlbwb2UtCx0E5mVfwj7w6xnWqJDTNCORqWEjQ0iYXSQZqsQ9zKVd2VSQQvKqjoRKiBMX29SC2YZCCcM0bQCrLAmQhfBjrPd9tlByQzob+bnBB775CW0Dg1alSrktkJ6zNSKyKCrHm5DR0hDwnxmapQOmXuAv1gNlU4evvLV+4xNL4tdZE+A0YBmpxgzbUlCm7CKzYu+RZtBV4doQL+WnkSQqMtGH8xyDA19AKnKTB8WA1sQpOjjJzmgqG8CTbkjpz3NUmjTFSUyvxQGFx138Y9Sp0igRhsqOz0tZaO6aOyjrgfG9KxBqkPXA6ld1DSEl99iN94ZKXDbKwGa9Uld/p6NhqWQtwNSv9DQ888yeoC+CPeETeJa58prBTWDwCDOT8QXbHDlG+PXs3JEmjmW41Cm8CXMcD8sVrR/ibHudx1gSWgw6/gbc9T9EvkrlXMRKHFjY2bTUlRJ7ZaJmif+QvdJyK9OF4VkImDWuQD/7inJcAzo4PmLjDihHcDywfFXikZdEUVT+8LZY8Gw30TtJEDeYA7vrZq9+GyxYpwR9Ne2D5r1bwPpNGCyX983WSatDGcN4mfPlfoaC1A/D03wgu/JoBtVJXlZHZFONK3T0N9/RNq2jXcNU3CfUQvswNc6w08nZWaN5Tn0tH60wzp2GP1fBHEqKTBY63LkIwqli1FAHlldXliHZnbf9znSsTt7vLaZjGjwUWAcldGH/eA3N8QsJJHmVe1JAffVKu0zsysM8HbvM6O68/kyS8uip6Pd8xKOKc3COBQag8porHX3gt6i2Do+J0IbVugRybMqjwLWNj/8GrwRfVo8pZ8RRX44ivFWikEcuHdx9DjRkPe+shJqUweo2DyV3j5XW2rlPflpFbhmm9KE1PwDHtdGIr6Jtz8oWDKugY9pf+KhjZigCYD1geW+BqFjoT1SjMbKerAy4HU5CW7eSBQGcyHHeOF8W1/PqysTxfkBRKHB4HpJE7Fg+/14fBcIo84a7pqGdMt6IQna6QWlnP1roizpumHXzIkikwSdwRddG70zD+CrwsmLBtoJ3AgAnDaiVcR/HbTGCfvXI7G67NFdqrrJJVcPVS9AN5pKR6WiQ2M4LyRyJ3TdIJFKIM+KJgUQwj+p23m6mbx/NRW4TDtwfROk8SgtCraJMaWvNHm/BINhmHTZN3Fwl8tNFDCWa4DsU2REzKOdP9nh1Mt11TglClg3KMPgoKDBqehYyXToQJwbYFyYeAyipJX9iTToBtxmSxOcKq5yaoJGZ4ajo8Zf0U3PRqAawupSn471cR1Kdh0H3P7MYOF3PpEShdwTupSPA9afMehIINHqKe5mOBAY8UwmdoP8Tan2fwD80h2+Mj6ejIU6sC/s4o/bWhIgLKS/rUp3zBmEO8ZLsrXrzVDQd1Sl7q5H/49NUL0zAABwmDmT0lpi2MVhIvqVN6WNCsqgHZ1vgypLkTiB2Krfeyc49RRXdIy0UlBO4iR5jTQZkKS/fQSEqwB6Yl1+uFTfUQoqY9SiEjssgm3hcXH/MzIN6eDwtvrrtwj4XBq0MXyuYn48faDFZVlDltTbUrXluXKLGCCUxSjhT4qIx5ken+gNAD8Q9YIEpS58iTvjl26y7hWE7R1PPJOEmXbFkcUJRlvVPPSTkaer9LupVwhOeQLUzYjql8CgaGrcaAC088T/CyYHiEa3FmDgxyof2fq8/og/8iYj5fSyNH2jgmB5Vm2G81/ur4Q3io/Lrv24+A0qmXVFE/xrhIJ3UGpyOomxnWy4WgiDNtev1NsuUNdUWNiKlCxHkIYwnifYqxehshSPo7NvArFJ1mVZvEPMb8jW/f9hO1bK+1uFoclPVDsPk3cUUOn0sU/WO3inwhh7r3wpvpSAGzR8UkeM07NlyLSU7k4poEsiMCPncNfSnjBiGdcvHgeUxH895xKsD9ugLa0zAp7Aq1kw4GPjXVmdTQjU3pCOKK+ulLsUEUmPe5zPp3Zl0KwFbM9kaqPCk1PBnWEbl7QHbV+GBJM8GIQYxwN6ACXQcRZccUbz5SqQWbQPxYgRBQPiIxbDgTZmeg886c8q4tXvi5ws8rHhbH3/c2EQTiDNSmVxA9ypI9TtDq+AQ1tPp7zNa/Y7MnkrvQtwxnZ2pFcTdM7tq4WX+Q6R9feqG78cpAxeDp/frQ+vHXA8DDcNBVB0mr2sk86WN2prCAaznePuG+075sOyo2nsvSyo58jtBajWUh5f5duRK4wTveKnPHrLqS0rrPnNhxhqBvpdYKFDR94lxGfCcCq08IQ34/lD2MNtnHW5aVug0KhUhOCHduVqFlAm/+TqmAKoIFf48KjkGZ93pvR8y7entbIQp0EA7YiP/vcwInz6TIaTe/EnX1f18pKuCu3uFbeCbsQfGIdLZS9L20LVEbDix7SymyfRu6dGgBEgrha4LvCE5iEc8Q4s42QF4cIW6L7rUF1QY5gXQAAVcAKeif8K3tj/djgtUrLUOAyscv4bLURV/5DKSO7IWFgwQVrGhF89shRh0zM1f3H+MPRgbb2X/nEpaGn8j7JFg2/luD19M6f3nW7UOqfJUWEypXz7WKjJ3pjc8Hr49Yuw4Wo8+VAnnKBTyioJePimOLP0Tjpiptx9bWTcAfhiV84xrMG6ktTs5tYZOoq5Mf0c5inObnrEdzk6p08KYAabU7iz8gT47Q/vgZ3qoeuRydTsVep+2PWwdMqNbCD8TCFJKpLntwMfUIm5z01KW/j8YcdMQStm0A0WdKgs2c4fEGpsYCrgeVV2bphfRbcy+HuVa0VVNG3S3tEEjQchT5jCA8QgcurX5Q2cbWPbVm7mPw==";
//        String enData = "aDgngzwWqrQrirlI/DlavIVO0CWwspVZmmX2hRMNmOR6gKo4HqfYI9Nfp+WabfL1sCR6a2o8AXgUz6AyJeL99FsMg4dhcGD7H7gsrFEHlYi5dowVNtUdFCpdHfKEoXchv9yjHj62dMyDJ2gm17zFY3UI6sVqCpQ3j+HUN0LO4gJjBaBeUDrl6feJhKAyAqwT";
        System.out.println(enData);
        String deData = AES_Decrypt(enData, key,"CBC");
        System.out.println(deData);
    }

}
